package FSMDE.models.tests;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.UUID;

import junit.framework.Assert;

import main.java.FSMDE.models.Diagram;
import main.java.FSMDE.models.FactoryTransition;
import main.java.FSMDE.models.Interface;
import main.java.FSMDE.models.InterfaceCollection;
import main.java.FSMDE.models.InterfaceGraphType;
import main.java.FSMDE.models.InterfaceType;
import main.java.FSMDE.models.Transition;
import main.java.FSMDE.models.TransitionCollection;

import org.junit.Test;


public class DiagramTestCase {

	@Test
	public void testCreatingDiagramProvidesContentsIsNone() {
		Diagram diagram = new Diagram();
		Assert.assertEquals(0, diagram.getInterfaces().count());
		Assert.assertEquals(0, diagram.getTransitions().count());
		Assert.assertEquals(0, diagram.getSubDiagrams().size());
		Assert.assertFalse(diagram.isFinalized());
	}

	@Test
	public void testCreateAnCompleteDiagram() {
		Diagram diagram = new Diagram(new InterfaceCollection(),
				new TransitionCollection(), new ArrayList<Diagram>(), false);

		Assert.assertEquals(0, diagram.getInterfaces().count());
		Assert.assertEquals(0, diagram.getTransitions().count());
		Assert.assertEquals(0, diagram.getSubDiagrams().size());
		Assert.assertNotNull(diagram.getSubDiagrams());
		Assert.assertEquals(0, diagram.getSubDiagrams().size());
		Assert.assertFalse(diagram.isFinalized());
	}

	@Test
	public void testTwoDiagramProvidesDifferentsIdNumbers() {
		Diagram diagram = new Diagram();
		Diagram diagram1 = new Diagram();
		Assert.assertTrue(diagram.getId().toString() != diagram1.getId()
				.toString());
	}

	@Test
	public void testAddingAnInterfaceCanBeRetrived() throws Exception {
		Diagram diagram = new Diagram();

		UUID uid1 = UUID.randomUUID();
		diagram.getInterfaces().add(
				new Interface(uid1, "TestName", InterfaceType.General,
						new TransitionCollection(), InterfaceGraphType.Normal));
		Assert.assertEquals(1, diagram.getInterfaces().count());
		Assert.assertEquals("TestName", diagram.getInterface(uid1).getName());
	}

	@Test
	public void testAddingTwoInterfacesCanBeRetrived() throws Exception {
		Diagram diagram = new Diagram();

		UUID uid1 = UUID.randomUUID();
		UUID uid2 = UUID.randomUUID();
		diagram.getInterfaces().add(
				new Interface(uid1, "TestName", InterfaceType.General,
						new TransitionCollection(), InterfaceGraphType.Normal));
		diagram.getInterfaces().add(
				new Interface(uid2, "TestName1", InterfaceType.General,
						new TransitionCollection(), InterfaceGraphType.Normal));
		Assert.assertEquals(2, diagram.getInterfaces().count());
		Assert.assertEquals("TestName", diagram.getInterface(uid1).getName());
		Assert.assertEquals("TestName1", diagram.getInterface(uid2).getName());
	}

	@Test
	public void testDelettingOneInterfaceAndANonExistentInterface()
			throws Exception {
		Diagram diagram = new Diagram();

		UUID id = UUID.randomUUID();
		diagram.getInterfaces().add(
				new Interface(id, "TestName", InterfaceType.General,
						new TransitionCollection(), InterfaceGraphType.Normal));
		Assert.assertTrue(diagram.existsInterface(id));

		try {
			diagram.removeInterface(id);
		} catch (Exception e) {
			fail();
		}
		Assert.assertFalse(diagram.existsInterface(id));

		id = UUID.randomUUID();
		try {
			diagram.removeInterface(id);
		} catch (Exception e) {
		}
	}

	@Test
	public void testReaddingATransitionFailure() throws Exception {
		Diagram diagram = new Diagram();

		UUID uid = UUID.randomUUID();
		Transition transition = FactoryTransition.createControlTransition(uid,
				"TestName");

		diagram.getTransitions().add(transition);
		Assert.assertEquals(1, diagram.getTransitions().count());
		Assert.assertTrue(diagram.existsTransition(uid));

		diagram.getTransitions().add(transition);
		Assert.assertEquals(1, diagram.getTransitions().count());
	}

	@Test
	public void testAddingAnIncompleteTransitionCanBeRetrived()
			throws Exception {
		Diagram diagram = new Diagram();

		UUID uid1 = UUID.randomUUID();
		UUID uid2 = UUID.randomUUID();
		Interface interface1 = new Interface(uid1, "TestName1",
				InterfaceType.General, new TransitionCollection(),
				InterfaceGraphType.Normal);
		Interface interface2 = new Interface(uid2, "TestName2",
				InterfaceType.General, new TransitionCollection(),
				InterfaceGraphType.Normal);
		diagram.getInterfaces().add(interface1);
		diagram.getInterfaces().add(interface2);

		UUID uid = UUID.randomUUID();
		Transition transition = FactoryTransition.createControlTransition(uid,
				"TestName");

		transition.setSource(interface1);

		diagram.getTransitions().add(transition);
		Assert.assertEquals(1, diagram.getTransitions().count());
		Assert.assertEquals("TestName", diagram.getTransition(uid).getName());
		Assert.assertFalse(transition.isEquilibrated());

		UUID uid4 = UUID.randomUUID();
		Transition transition2 = FactoryTransition.createControlTransition(
				uid4, "TestName2");

		transition2.setDestination(interface2);

		diagram.getTransitions().add(transition2);
		Assert.assertEquals(2, diagram.getTransitions().count());
		Assert.assertEquals("TestName2", diagram.getTransition(uid4).getName());
		Assert.assertFalse(transition2.isEquilibrated());
	}

	@Test
	public void testAddingACompleteTransitionCanBeRetrived() throws Exception {
		Diagram diagram = new Diagram();

		UUID uid1 = UUID.randomUUID();
		UUID uid2 = UUID.randomUUID();
		Interface interface1 = new Interface(uid1, "TestName1",
				InterfaceType.General, new TransitionCollection(),
				InterfaceGraphType.Normal);
		Interface interface2 = new Interface(uid2, "TestName2",
				InterfaceType.General, new TransitionCollection(),
				InterfaceGraphType.Normal);
		diagram.getInterfaces().add(interface1);
		diagram.getInterfaces().add(interface2);

		UUID uid = UUID.randomUUID();
		Transition transition = FactoryTransition.createControlTransition(uid,
				"TestName");

		transition.setSource(interface1);
		transition.setDestination(interface2);

		diagram.getTransitions().add(transition);
		Assert.assertEquals(1, diagram.getTransitions().count());
		Assert.assertEquals("TestName", diagram.getTransition(uid).getName());
		Assert.assertTrue(transition.isEquilibrated());
	}

	@Test
	public void testAddingTwoTransitionsCanBeRetrived() throws Exception {
		Diagram diagram = new Diagram();

		UUID uid1 = UUID.randomUUID();
		UUID uid2 = UUID.randomUUID();
		Interface interface1 = new Interface(uid1, "TestName1",
				InterfaceType.General, new TransitionCollection(),
				InterfaceGraphType.Normal);
		Interface interface2 = new Interface(uid2, "TestName2",
				InterfaceType.General, new TransitionCollection(),
				InterfaceGraphType.Normal);
		diagram.getInterfaces().add(interface1);
		diagram.getInterfaces().add(interface2);

		UUID uid3 = UUID.randomUUID();
		Transition transition1 = FactoryTransition.createControlTransition(
				uid3, "TestName3");

		transition1.setSource(interface1);
		transition1.setDestination(interface2);

		UUID uid4 = UUID.randomUUID();
		Transition transition2 = FactoryTransition.createControlTransition(
				uid4, "TestName4");

		transition2.setSource(interface1);
		transition2.setDestination(interface2);

		diagram.getTransitions().add(transition1);
		diagram.getTransitions().add(transition2);
		Assert.assertEquals(2, diagram.getTransitions().count());
		Assert.assertEquals("TestName3", diagram.getTransition(uid3).getName());
		Assert.assertEquals("TestName4", diagram.getTransition(uid4).getName());
	}

	@Test
	public void testDelettingOneTransitionAndANonExistentTransition()
			throws Exception {
		Diagram diagram = new Diagram();
		UUID uid1 = UUID.randomUUID();
		UUID uid2 = UUID.randomUUID();
		Interface interface1 = new Interface(uid1, "TestName1",
				InterfaceType.General, new TransitionCollection(),
				InterfaceGraphType.Normal);
		Interface interface2 = new Interface(uid2, "TestName2",
				InterfaceType.General, new TransitionCollection(),
				InterfaceGraphType.Normal);
		diagram.getInterfaces().add(interface1);
		diagram.getInterfaces().add(interface2);

		UUID id = UUID.randomUUID();
		Transition transition = FactoryTransition.createControlTransition(id,
				"TestName");
		transition.setSource(interface1);
		transition.setDestination(interface2);

		diagram.getTransitions().add(transition);
		Assert.assertTrue(diagram.existsTransition(id));

		try {
			diagram.removeTransition(id);
		} catch (Exception e) {
			fail();
		}
		Assert.assertFalse(diagram.existsTransition(id));

		id = UUID.randomUUID();
		try {
			diagram.removeTransition(id);
		} catch (Exception e) {
		}
	}

	@Test
	public void testAddingASubdiagramCanBeRetrived() {
		Diagram diagram = new Diagram();
		Diagram diagram2 = new Diagram();

		diagram.addSubDiagram(diagram2);
		Assert.assertTrue(diagram.existsSubDiagram(diagram2.getId()));
		Assert.assertEquals(diagram2.getId().toString(),
				diagram.getSubDiagram(diagram2.getId()).getId().toString());
	}

	@Test
	public void testAddingTwoSubDiagrams() {
		Diagram diagram = new Diagram();
		Diagram diagram2 = new Diagram();
		Diagram diagram3 = new Diagram();

		diagram.addSubDiagram(diagram2);
		diagram.addSubDiagram(diagram3);
		Assert.assertEquals(diagram2.getId().toString(),
				diagram.getSubDiagram(diagram2.getId()).getId().toString());
		Assert.assertEquals(diagram3.getId().toString(),
				diagram.getSubDiagram(diagram3.getId()).getId().toString());
		Assert.assertTrue(diagram2.getId().toString() != diagram3.getId()
				.toString());
	}

	@Test
	public void testRemovingExistentAndNonExistentSubDiagrams() {
		Diagram diagram = new Diagram();
		UUID id = UUID.randomUUID();
		try {
			diagram.removeSubDiagram(id);
		} catch (Exception e) {
		}

		Diagram diagram2 = new Diagram();
		diagram.addSubDiagram(diagram2);
		try {
			diagram.removeSubDiagram(diagram2.getId());
		} catch (Exception e) {
			fail();
		}
	}

	@Test
	public void testCheckingTransitionsFinalizationState() throws Exception {
		Diagram diagram = new Diagram();

		UUID uid1 = UUID.randomUUID();
		UUID uid2 = UUID.randomUUID();
		Interface interface1 = new Interface(uid1, "TestName1",
				InterfaceType.General, new TransitionCollection(),
				InterfaceGraphType.Normal);
		Interface interface2 = new Interface(uid2, "TestName2",
				InterfaceType.General, new TransitionCollection(),
				InterfaceGraphType.Normal);
		diagram.getInterfaces().add(interface1);
		diagram.getInterfaces().add(interface2);

		UUID uid3 = UUID.randomUUID();
		Transition transition1 = FactoryTransition.createControlTransition(
				uid3, "TestName3");
		transition1.setSource(interface1);
		diagram.getTransitions().add(transition1);

		diagram.finalizeDiagram();
		Assert.assertFalse(diagram.isFinalized());

		UUID uid4 = UUID.randomUUID();
		Transition transition2 = FactoryTransition.createControlTransition(
				uid4, "TestName4");
		transition2.setSource(interface1);
		transition2.setDestination(interface2);
		diagram.getTransitions().add(transition2);

		diagram.finalizeDiagram();
		Assert.assertFalse(diagram.isFinalized());

		transition1.setDestination(interface2);

		diagram.finalizeDiagram();
		Assert.assertTrue(diagram.isFinalized());
	}
}
